.TH std::ranges::empty 3 "2024.06.10" "http://cppreference.com" "C++ Standard Libary"
.SH NAME
std::ranges::empty \- std::ranges::empty

.SH Synopsis
   Defined in header <ranges>
   Defined in header <iterator>
   inline namespace /*unspecified*/ {
                                                       \fI(since C++20)\fP
       inline constexpr auto empty = /*unspecified*/;  (customization point object)

   }
   Call signature
   template< class T >

       requires /* see below */                        \fI(since C++20)\fP

   constexpr bool empty( T&& t );

   Determines whether or not t has any elements.

   A call to ranges::empty is expression-equivalent to:

    1. bool(t.empty()), if that expression is valid.
    2. Otherwise, (ranges::size(t) == 0), if that expression is valid.
    3. Otherwise, bool(ranges::begin(t) == ranges::end(t)), if that expression is valid
       and decltype(ranges::begin(t)) models std::forward_iterator.

   In all other cases, a call to ranges::empty is ill-formed, which can result in
   substitution failure when ranges::empty(t) appears in the immediate context of a
   template instantiation.

  Customization point objects

   The name ranges::empty denotes a customization point object, which is a const
   function object of a literal semiregular class type. For exposition purposes, the
   cv-unqualified version of its type is denoted as __empty_fn.

   All instances of __empty_fn are equal. The effects of invoking different instances
   of type __empty_fn on the same arguments are equivalent, regardless of whether the
   expression denoting the instance is an lvalue or rvalue, and is const-qualified or
   not (however, a volatile-qualified instance is not required to be invocable). Thus,
   ranges::empty can be copied freely and its copies can be used interchangeably.

   Given a set of types Args..., if std::declval<Args>()... meet the requirements for
   arguments to ranges::empty above, __empty_fn models

     * std::invocable<__empty_fn, Args...>,
     * std::invocable<const __empty_fn, Args...>,
     * std::invocable<__empty_fn&, Args...>, and
     * std::invocable<const __empty_fn&, Args...>.

   Otherwise, no function call operator of __empty_fn participates in overload
   resolution.

.SH Example


// Run this code

 #include <iostream>
 #include <ranges>
 #include <vector>

 template<std::ranges::input_range R>
 void print(char id, R&& r)
 {
     if (std::ranges::empty(r))
     {
         std::cout << '\\t' << id << ") Empty\\n";
         return;
     }

     std::cout << '\\t' << id << ") Elements:";
     for (const auto& element : r)
         std::cout << ' ' << element;
     std::cout << '\\n';
 }

 int main()
 {
     {
         auto v = std::vector<int>{1, 2, 3};
         std::cout << "(1) ranges::empty uses std::vector::empty:\\n";
         print('a', v);

         v.clear();
         print('b', v);
     }
     {
         std::cout << "(2) ranges::empty uses ranges::size(initializer_list):\\n";
         auto il = {7, 8, 9};
         print('a', il);

         print('b', std::initializer_list<int>{});
     }
     {
         std::cout << "(2) ranges::empty on a raw array uses ranges::size:\\n";
         int array[] = {4, 5, 6}; // array has a known bound
         print('a', array);
     }
     {
         struct Scanty : private std::vector<int>
         {
             using std::vector<int>::begin;
             using std::vector<int>::end;
             using std::vector<int>::push_back;
             // Note: both empty() and size() are hidden
         };

         std::cout << "(3) calling ranges::empty on an object w/o empty() or size():\\n";
         Scanty y;
         print('a', y);
         y.push_back(42);
         print('b', y);
     }
 }

.SH Output:

 \fB(1)\fP ranges::empty uses std::vector::empty:
         a) Elements: 1 2 3
         b) Empty
 \fB(2)\fP ranges::empty uses ranges::size(initializer_list):
         a) Elements: 7 8 9
         b) Empty
 \fB(2)\fP ranges::empty on a raw array uses ranges::size:
         a) Elements: 4 5 6
 \fB(3)\fP calling ranges::empty on an object w/o empty() or size():
         a) Empty
         b) Elements: 42

.SH See also

   empty   checks whether the container is empty
   \fI(C++17)\fP \fI(function template)\fP
